package coupon

import (
	"context"
	"strconv"
	"strings"

	"mall/common/globalkey"
	"mall/common/jwt"
	"mall/common/utils/pointy"
	enum "mall/service/backend/common/enum/promotion"
	"mall/service/forum/api/internal/logic/promotion/util"
	"mall/service/forum/api/internal/svc"
	"mall/service/forum/api/internal/types"
	"mall/service/promotion/rpc/promotionclient"

	"github.com/zeromicro/go-zero/core/logx"
)

type GetCouponTemplateByIdLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewGetCouponTemplateByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetCouponTemplateByIdLogic {
	return &GetCouponTemplateByIdLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *GetCouponTemplateByIdLogic) GetCouponTemplateById(
	req *types.GetCouponTemplateByIdReq,
	headers *[]*types.Header,
) (resp *types.CouponTemplateInfo, err error) {
	if req.Id == nil || *req.Id == 0 {
		return &types.CouponTemplateInfo{}, nil
	}

	userId := jwt.GetUserId(l.ctx)

	// Todo: 删除无用字段
	preload := "couponTemplate:Id,Name,Desc,Members,Type,Mutex,Scope,Mode,Threshhold,DiscountMode,DiscountValue," +
		"GemPrice,PerLimit,ExpireMode,ExpireValue,StartedAt,EndedAt"
	preload += ";promotionMeta:mediaUrl"
	preload += ";promotionMedia:Uid,Uri,Url,Thumbnail,Order,altText"
	eagerLoad := "couponTemplate:couponTotal,promotionMeta,promotionMedia"

	var filters []string
	filters = append(filters, "Status,equalTo:"+strconv.FormatInt(int64(globalkey.StatusStarted), 10))
	if req.ScopeType != nil {
		filters = append(filters, "Scope,equalTo:"+strconv.FormatInt(int64(*req.ScopeType), 10))
	}

	res, err := l.svcCtx.PromotionRpc.GetCouponTemlateById(l.ctx, &promotionclient.BaseIdReq{
		Id:         req.Id,
		Preload:    pointy.GetPointer(preload),
		EagerLoad:  pointy.GetPointer(eagerLoad),
		Filter:     pointy.GetPointer(strings.Join(filters, ";")),
		VisitorId:  pointy.GetPointer(userId),
		PlatformId: pointy.GetPointer(globalkey.ThirdPartyPlatformWechatMini),
	})
	if err != nil {
		logx.Errorw("GetCouponTemplateById err", logx.Field("detail", err.Error()))
		return &types.CouponTemplateInfo{}, nil
	}

	var timeRange []string
	if res.StartedAt != nil && res.EndedAt != nil {
		timeRange = []string{*res.StartedAt, *res.EndedAt}
	}

	couponTypeText := util.GetCouponTypeText(res.CouponType)
	mutexTypeText := util.GetMutexTypeText(res.MutexType)
	scopeTypeText := util.GetScopeTypeText(res.ScopeType)
	modeText := util.GetCouponModeText(res.Condition)
	var threshold *string
	if res.ConditionValue != nil {
		if tips := strings.Split(modeText, ","); len(tips) > 0 && len(tips[0]) > 0 {
			threshold = pointy.GetPointer(strings.Replace(tips[0], "N", *res.ConditionValue, 1))
		}
	}
	var discount *string
	if res.DiscountMode != nil && res.DiscountValue != nil {
		discount = pointy.GetPointer(util.GetDiscountValue(res.DiscountMode, res.DiscountValue))
	}
	expireModeText := util.GetExpireModeText(res.ExpireMode)
	var expire string
	if res.ExpireMode != nil && res.ExpireValue != nil && *res.ExpireMode == uint32(enum.PromotionCouponExpireDynamic) {
		expire = "有效期: 自领取后" + strconv.FormatInt(int64(*res.ExpireValue), 10) + "天"
	}
	if res.ExpireMode != nil && len(timeRange) > 0 && *res.ExpireMode == uint32(enum.PromotionCouponExpireStatic) {
		expire = "有效期: " + strings.Join(timeRange, "-")
	}
	statusText := util.GetCouponStatusText(res.Status)

	var canReceive bool
	if res.PerLimit == nil || *res.PerLimit == 0 {
		canReceive = true
	} else if res.CouponTotal != nil && *res.PerLimit > *res.CouponTotal {
		canReceive = true
	}

	var mediaUrl *string
	if len(res.Meta) > 0 {
		for _, m := range res.Meta {
			if m.Key == nil || m.Value == nil {
				continue
			}

			switch *m.Key {
			case "mediaUrl":
				mediaUrl = m.Value
			}
		}
	}

	var media []*types.TmpMediaInfo
	if len(res.Media) > 0 {
		for _, m := range res.Media {
			var url string
			if m.Url != nil && len(*m.Url) > 0 {
				url = *m.Url
			}
			if len(url) == 0 && m.Uri != nil && len(*m.Uri) > 0 {
				url = *m.Uri
			}

			media = append(media, &types.TmpMediaInfo{
				Uid:       m.Uid,
				Thumbnail: m.Thumbnail,
				Order:     m.Order,
				Url:       pointy.GetPointer(url),
				AltText:   m.AltText,
			})
		}
	} else if mediaUrl != nil {
		media = append(media, &types.TmpMediaInfo{
			Thumbnail: pointy.GetPointer(uint32(1)),
			Order:     pointy.GetPointer(uint32(0)),
			Url:       mediaUrl,
		})
	}

	resp = &types.CouponTemplateInfo{
		Id:                res.Id,
		Name:              res.Name,
		Description:       res.Desc,
		MemberRestriction: res.MemberRestriction,
		CouponType:        res.CouponType,
		CouponTypeText:    pointy.GetPointer(couponTypeText),
		MutexType:         res.MutexType,
		MutexTypeText:     pointy.GetPointer(mutexTypeText),
		ScopeType:         res.ScopeType,
		ScopeTypeText:     pointy.GetPointer(scopeTypeText),
		Mode:              res.Condition,
		ModeText:          pointy.GetPointer(modeText),
		Threshold:         threshold,
		DiscountMode:      res.DiscountMode,
		Discount:          discount,
		PerLimit:          res.PerLimit,
		TimeRange:         timeRange,
		ExpireMode:        res.ExpireMode,
		ExpireModeText:    pointy.GetPointer(expireModeText),
		ExpireValue:       res.ExpireValue,
		Expire:            pointy.GetPointer(expire),
		Status:            res.Status,
		StatusText:        pointy.GetPointer(statusText),
		GemPrice:          res.GemPrice,
		Count:             res.Count,
		CouponTotal:       res.CouponTotal,
		CanReceive:        canReceive,
		Media:             media,
	}

	return resp, nil
}
